using System;
using System.Collections.Generic;
using System.Linq;

namespace Nvigorate.Common.Reflection
{
    internal class TypeEquivalenceComparer : IEqualityComparer<Type>
    {
        public bool Equals(Type x, Type y)
        {
            return 
                CheckBasics(x, y) ||
                (x.IsGenericParameter && CheckPassConstrains(y, x.GetGenericParameterConstraints())) ||
                (y.IsGenericParameter && CheckPassConstrains(x, y.GetGenericParameterConstraints()));
        }

        protected bool CheckBasics(Type x, Type y)
        {
            return x.Equals(y) || 
                   x.IsSubclassOf(y) || 
                   y.IsSubclassOf(x) || 
                   x.GetInterface(y.Name) != null || 
                   y.GetInterface(x.Name) != null;
        }

        public bool CheckPassConstrains(Type x, Type[] constraints)
        {
            if(constraints.Length == 0)
                return true;
            return constraints.All(c => CheckBasics(x, c));
        }

        public int GetHashCode(Type obj)
        {
            return obj.GetHashCode();
        }
    }
}